﻿#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<string.h>

//常见错误
//对NULL指针的解引⽤操作
//void test()
//{
//	int* p = (int*)malloc(sizeof(int));
//	*p = 20;//如果p的值是NULL，就会有问题
//	free(p);
//}

////越界访问
//void test()
//{
//	int i = 0;
//	int* p = (int*)malloc(10 * sizeof(int));
//	//开辟10个整型大小的空间
//	if (NULL == p)
//	{
//		perror("malloc");
//		exit(1);
//	}
//	for (i = 0; i <= 10; i++)
//	{
//		*(p + i) = i;//当i是10的时候越界访问
//	}
//	free(p);
//	p = NULL;
//}

////对非动态开辟内存使用free释放
//void test()
//{
//	int* p = NULL;
//	int a = 10;
//	p = &a;
//	free(p);
//	//p不是动态内存开辟的
//}

//使用free释放⼀块动态开辟内存的⼀部分
//void test()
//{
//	int* p = (int*)malloc(10 * sizeof(int));
//	p++;
//	free(p);//p不再指向动态内存的起始位置
//}


////对同一块动态内存开辟的空间进行重复释放
//void test()
//{
//	int* p = (int*)malloc(10 * sizeof(int));
//	free(p);
//	free(p);//重复释放
//}
// 
// 
//// 动态开辟内存忘记释放（内存泄漏）
//
//void test()
//{
//	int* p = (int*)malloc(sizeof(int));
//	if (NULL != p)
//	{
//		*p = 20;
//	}
//	//调用了test函数进行了动态内存开辟
//	//但是没有进行释放
//}


//动态内存题目分析
//void GetMemory(char* p)
//{
//	p = (char*)malloc(100);
//}
//void test(void)
//{
//	char* str = NULL;
//	GetMemory(str);
//	strcpy(str, "hello world");
//	printf(str);
//}


//正确代码

//void GetMemory(char** p)
//{
//	*p = (char*)malloc(100);
//	if (*p == NULL)
//	{
//		perror("malloc");
//		exit(1);
//	}
//}
//void test(void)
//{
//	char* str = NULL;
//	GetMemory(&str);
//	strcpy(str, "hello world");
//	printf(str);
//}
////void test()
//{
//	int* p = (int*)malloc(sizeof(int));
//	if (p == NULL)
//	{
//		perror("malloc");//显示错误
//		exit(1);//退出程序
//	}
//	*p = 20;//如果p的值是NULL，就会有问题
//	free(p);
//	p = NULL;
//}
//int main()
//{
//	test();
//	return 0;
//}


////柔性数组
//struct st_type
//{
//	int i;
//	int a[0];//柔性数组成员
//};
////一些编译器可能报错，可以改成：
//
//struct st_type
//{
//	int i;
//	int a[];//柔性数组成员
//};


//typedef struct st_type
//{
//	int i;
//	int a[0];//柔性数组成员
//}type_a;
//int main()
//{
//	printf("%zd\n", sizeof(type_a));//输出的是4
//	return 0;
//}

//typedef struct st_type
//{
//	int i;
//	int a[0];//柔性数组成员
//}type_a;
////代码1：
//int main()
//{
//	int i = 0;
//	type_a* p = (type_a*)malloc(sizeof(type_a) + 100 * sizeof(int));
//	if (p == NULL)
//	{
//		perror("malloc");
//		exit(1);
//	}
//	//业务处理
//	p->i = 100;
//	for (i = 0; i < 100; i++)
//	{
//		p->a[i] = i;
//		printf("%5d ", p->a[i]);
//	}
//	free(p);
//	return 0;
//}



////代码2
//typedef struct st_type
//{
//	int i;
//	int* p_a;
//}type_a;
//int main()
//{
//	type_a* p = (type_a*)malloc(sizeof(type_a));
//	if (p == NULL)
//	{
//		perror("malloc");
//		exit(1);
//	}
//	p->i = 100;
//	p->p_a = (int*)malloc(p->i * sizeof(int));
//	if (p->p_a == NULL)
//	{
//		perror("malloc");
//		exit(1);
//	}
//	//业务处理
//	for (int i = 0; i < 100; i++)
//	{
//		p->p_a[i] = i;
//		printf("%5d", p->p_a[i]);
//	}
//
//	//释放空间
//	free(p->p_a);
//	p->p_a = NULL;
//	free(p);
//	p = NULL;
//	return 0;
//}


//void GetMemory(char** p)
//{
//	*p = (char*)malloc(100);
//	//操作的是同一个地址
//}
//void test(void)
//{
//	char* str = NULL;
//	GetMemory(&str);//指针变量传地址
//	strcpy(str, "hello world");
//	printf(str);
//	free(str);//动态申请内存空间进行释放
//	str = NULL;
//}


//char* GetMemory()
//{
//	char* p = (char*)malloc(100);
//	return p;
//}
//void test(void)
//{
//	char* str = NULL;
//	str = GetMemory();//str得到一块内存空间
//	strcpy(str, "hello world");
//	printf(str);
//	free(str);//动态申请内存空间进行释放
//	str = NULL;
//}

//
//char* GetMemory(void)
//{
//	char p[] = "hello world";
//	return p;//栈区的局部变量，函数调用结束被销毁
//}
//void test(void)
//{
//	char* str = NULL;
//	str = GetMemory();
//	printf(str);
//}
//

//
//void GetMemory(char** p, int num)
//{
//	*p = (char*)malloc(num);
//}
//void test(void)
//{
//	char* str = NULL;
//	GetMemory(&str, 100);
//	strcpy(str, "hello");
//	printf(str);
//	free(str);
//	str = NULL;
//}



void test(void)
{
	char* str = (char*)malloc(100);
	strcpy(str, "hello");
	printf(str);

	free(str);//str没有及时置为空，str成为野指针，指向一块内存空间
	if (str != NULL)
	{
		strcpy(str, "world");//非法访问
		printf(str);
	}
}


//修改

//void test(void)
//{
//	char* str = (char*)malloc(100);
//	if (str == NULL)
//	{
//		perror("malloc");
//		exit(1);//创建失败退出程序
//	}
//	strcpy(str, "hello");
//	printf(str);
//	//printf("world");
//	free(str);//str及时置为空，避免str成为野指针
//	str = NULL;
//	if (str != NULL)
//	{
//		strcpy(str, "world");
//		printf(str);
//	}
//}
int main()
{
	test();
	return 0;
}